﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace Slock.Utility
{
    /// <summary>
    /// Stores rotation information
    /// </summary>
    public struct Rotator
    {
        #region Globals

        /// <summary>
        /// Get a zeroed out Rotator
        /// </summary>
        public static Rotator Zero
        { get { return new Rotator() { pitch = 0, yaw = 0, roll = 0 }; } }

        #endregion

        #region Fields

        private float yaw;
        private float pitch;
        private float roll;

        #endregion

        /// <summary>
        /// Initializes a new instace of Rotator
        /// </summary>
        /// <param name="yawRot"></param>
        /// <param name="pitchRot"></param>
        /// <param name="rollRot"></param>
        public Rotator(ref float yawRot, ref float pitchRot, ref float rollRot)
        {
            yaw = yawRot;
            pitch = pitchRot;
            roll = rollRot;
        }

        /// <summary>
        /// Initializes a new instance of Rotator
        /// </summary>
        /// <param name="yawRot"></param>
        /// <param name="pitchRot"></param>
        /// <param name="rollRot"></param>
        public Rotator(float yawRot, float pitchRot, float rollRot) : this(ref yawRot, ref pitchRot, ref rollRot)
        { }

        #region Methods

        /// <summary>
        /// Gets a rotation as a quaternion
        /// </summary>
        /// <param name="quaternion"></param>
        public void GetRotationAsQuaternion(out Quaternion quaternion)
        {
            // feeling uneasy about this one, since you can modify the coordinate system on the fly
            // that feature should probably be removed
            quaternion = Quaternion.CreateFromYawPitchRoll(yaw, pitch, roll);
        }

        /// <summary>
        /// Gets a rotation as a quaternion
        /// </summary>
        public Quaternion GetRotationAsQuaternion()
        {
            Quaternion q;
            GetRotationAsQuaternion(out q);
            return q;
        }

        /// <summary>
        /// Get a rotation as a matrix
        /// </summary>
        /// <param name="rotationMatrix"></param>
        /// <returns></returns>
        public void GetRotationAsMatrix(out Matrix rotationMatrix)
        {
            Matrix.CreateFromYawPitchRoll(yaw, pitch, roll, out rotationMatrix);
        }

        /// <summary>
        /// Get a rotation as a matrix
        /// </summary>
        /// <param name="rotationMatrix"></param>
        /// <returns></returns>
        public Matrix GetRotationAsMatrix()
        {
            return Matrix.CreateFromYawPitchRoll(yaw, pitch, roll);
        }

        /// <summary>
        /// Gets this rotator as a vector3
        /// </summary>
        /// <returns></returns>
        public Vector3 ToVector3()
        {
            return new Vector3(Roll, Yaw, Pitch);
        }

        #endregion

        #region Properties

        /// <summary>
        /// Get or set the Yaw
        /// </summary>
        public float Yaw
        {
            get { return this.yaw; }
            set { this.yaw = value; }
        }

        /// <summary>
        /// Get or set the pitch
        /// </summary>
        public float Pitch
        {
            get { return this.pitch; }
            set { this.pitch = value; }
        }

        /// <summary>
        /// Get or set the roll
        /// </summary>
        public float Roll
        {
            get { return this.roll; }
            set { this.roll = value; }
        }

        #endregion

    }
}
